/**
*  deferredconfirm.h
*
*  @copyright 2016
*/

/**
*  Include guard
*/
#pragma once

/**
*  Dependencies
*/
#include "deferred.h"

/**
*  Start namespace
*/
namespace AMQP {

	/**
	*  Forward declarations
	*/
	class BasicAckFrame;
	class BasicNackFrame;

	/**
	*  Base class for deferred return
	*/
	class DeferredConfirm :	public Deferred
	{
	private:
		/**
		*  Callback to execute when a ack or nack return
		*  @var    AckCallback
		*/
		AckCallback	_ackCallback;

		/**
		*  Process the ack
		*
		*  @param  frame   The frame to process
		*/
		void process(BasicAckFrame* ack);

		/**
		*  Process the ack
		*
		*  @param  frame   The frame to process
		*/
		void process(BasicNackFrame* ack);

		/**
		*  The channel implementation may call our
		*  private members and construct us
		*/
		friend class ChannelImpl;
		friend class BasicAckFrame;
		friend class BasicNackFrame;

	public:
		/**
		*  Protected constructor that can only be called
		*  from within the channel implementation
		*
		*  Note: this constructor _should_ be protected, but because make_shared
		*  will then not work, we have decided to make it public after all,
		*  because the work-around would result in not-so-easy-to-read code.
		*
		*  @param  bool    are we already failed?
		*/
		DeferredConfirm(bool failed = false) : Deferred(failed) {}

	public:
		/**
		*  Register a function to be called when a ack or nack back
		*
		*  Only one callback can be registered. Successive calls
		*  to this function will clear callbacks registered before.
		*
		*  @param  callback    the callback to execute
		*/
		DeferredConfirm &onAck(const AckCallback &callback)
		{
			// store callback
			_ackCallback = callback;

			// allow chaining
			return *this;
		}
	};
}